/*
 * Copyright (C) 1997-2001 Id Software, Inc.
 * 
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation; either version 2 of the License, or (at your option) any later
 * version.
 * 
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE.
 * 
 * See the GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License along with
 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
 * Place - Suite 330, Boston, MA 02111-1307, USA.
 *  
 */
/* Modifications
   Copyright 2003-2004 Bytonic Software
   Copyright 2010 Google Inc.
*/
package com.googlecode.playnquake.core.game.monsters;

import com.googlecode.playnquake.core.common.Constants;
import com.googlecode.playnquake.core.game.*;
import com.googlecode.playnquake.core.game.adapters.EntInteractAdapter;
import com.googlecode.playnquake.core.game.adapters.EntityDieAdapter;
import com.googlecode.playnquake.core.game.adapters.EntityPainAdapter;
import com.googlecode.playnquake.core.game.adapters.EntityThinkAdapter;
import com.googlecode.playnquake.core.server.ServerGame;
import com.googlecode.playnquake.core.server.ServerInit;
import com.googlecode.playnquake.core.server.World;
import com.googlecode.playnquake.core.util.Lib;
import com.googlecode.playnquake.core.util.Math3D;


public class MonsterTank {
    // G:\quake2\baseq2\models/monsters/tank

    // This file generated by qdata - Do NOT Modify

    public final static int FRAME_stand01 = 0;

    public final static int FRAME_stand02 = 1;

    public final static int FRAME_stand03 = 2;

    public final static int FRAME_stand04 = 3;

    public final static int FRAME_stand05 = 4;

    public final static int FRAME_stand06 = 5;

    public final static int FRAME_stand07 = 6;

    public final static int FRAME_stand08 = 7;

    public final static int FRAME_stand09 = 8;

    public final static int FRAME_stand10 = 9;

    public final static int FRAME_stand11 = 10;

    public final static int FRAME_stand12 = 11;

    public final static int FRAME_stand13 = 12;

    public final static int FRAME_stand14 = 13;

    public final static int FRAME_stand15 = 14;

    public final static int FRAME_stand16 = 15;

    public final static int FRAME_stand17 = 16;

    public final static int FRAME_stand18 = 17;

    public final static int FRAME_stand19 = 18;

    public final static int FRAME_stand20 = 19;

    public final static int FRAME_stand21 = 20;

    public final static int FRAME_stand22 = 21;

    public final static int FRAME_stand23 = 22;

    public final static int FRAME_stand24 = 23;

    public final static int FRAME_stand25 = 24;

    public final static int FRAME_stand26 = 25;

    public final static int FRAME_stand27 = 26;

    public final static int FRAME_stand28 = 27;

    public final static int FRAME_stand29 = 28;

    public final static int FRAME_stand30 = 29;

    public final static int FRAME_walk01 = 30;

    public final static int FRAME_walk02 = 31;

    public final static int FRAME_walk03 = 32;

    public final static int FRAME_walk04 = 33;

    public final static int FRAME_walk05 = 34;

    public final static int FRAME_walk06 = 35;

    public final static int FRAME_walk07 = 36;

    public final static int FRAME_walk08 = 37;

    public final static int FRAME_walk09 = 38;

    public final static int FRAME_walk10 = 39;

    public final static int FRAME_walk11 = 40;

    public final static int FRAME_walk12 = 41;

    public final static int FRAME_walk13 = 42;

    public final static int FRAME_walk14 = 43;

    public final static int FRAME_walk15 = 44;

    public final static int FRAME_walk16 = 45;

    public final static int FRAME_walk17 = 46;

    public final static int FRAME_walk18 = 47;

    public final static int FRAME_walk19 = 48;

    public final static int FRAME_walk20 = 49;

    public final static int FRAME_walk21 = 50;

    public final static int FRAME_walk22 = 51;

    public final static int FRAME_walk23 = 52;

    public final static int FRAME_walk24 = 53;

    public final static int FRAME_walk25 = 54;

    public final static int FRAME_attak101 = 55;

    public final static int FRAME_attak102 = 56;

    public final static int FRAME_attak103 = 57;

    public final static int FRAME_attak104 = 58;

    public final static int FRAME_attak105 = 59;

    public final static int FRAME_attak106 = 60;

    public final static int FRAME_attak107 = 61;

    public final static int FRAME_attak108 = 62;

    public final static int FRAME_attak109 = 63;

    public final static int FRAME_attak110 = 64;

    public final static int FRAME_attak111 = 65;

    public final static int FRAME_attak112 = 66;

    public final static int FRAME_attak113 = 67;

    public final static int FRAME_attak114 = 68;

    public final static int FRAME_attak115 = 69;

    public final static int FRAME_attak116 = 70;

    public final static int FRAME_attak117 = 71;

    public final static int FRAME_attak118 = 72;

    public final static int FRAME_attak119 = 73;

    public final static int FRAME_attak120 = 74;

    public final static int FRAME_attak121 = 75;

    public final static int FRAME_attak122 = 76;

    public final static int FRAME_attak201 = 77;

    public final static int FRAME_attak202 = 78;

    public final static int FRAME_attak203 = 79;

    public final static int FRAME_attak204 = 80;

    public final static int FRAME_attak205 = 81;

    public final static int FRAME_attak206 = 82;

    public final static int FRAME_attak207 = 83;

    public final static int FRAME_attak208 = 84;

    public final static int FRAME_attak209 = 85;

    public final static int FRAME_attak210 = 86;

    public final static int FRAME_attak211 = 87;

    public final static int FRAME_attak212 = 88;

    public final static int FRAME_attak213 = 89;

    public final static int FRAME_attak214 = 90;

    public final static int FRAME_attak215 = 91;

    public final static int FRAME_attak216 = 92;

    public final static int FRAME_attak217 = 93;

    public final static int FRAME_attak218 = 94;

    public final static int FRAME_attak219 = 95;

    public final static int FRAME_attak220 = 96;

    public final static int FRAME_attak221 = 97;

    public final static int FRAME_attak222 = 98;

    public final static int FRAME_attak223 = 99;

    public final static int FRAME_attak224 = 100;

    public final static int FRAME_attak225 = 101;

    public final static int FRAME_attak226 = 102;

    public final static int FRAME_attak227 = 103;

    public final static int FRAME_attak228 = 104;

    public final static int FRAME_attak229 = 105;

    public final static int FRAME_attak230 = 106;

    public final static int FRAME_attak231 = 107;

    public final static int FRAME_attak232 = 108;

    public final static int FRAME_attak233 = 109;

    public final static int FRAME_attak234 = 110;

    public final static int FRAME_attak235 = 111;

    public final static int FRAME_attak236 = 112;

    public final static int FRAME_attak237 = 113;

    public final static int FRAME_attak238 = 114;

    public final static int FRAME_attak301 = 115;

    public final static int FRAME_attak302 = 116;

    public final static int FRAME_attak303 = 117;

    public final static int FRAME_attak304 = 118;

    public final static int FRAME_attak305 = 119;

    public final static int FRAME_attak306 = 120;

    public final static int FRAME_attak307 = 121;

    public final static int FRAME_attak308 = 122;

    public final static int FRAME_attak309 = 123;

    public final static int FRAME_attak310 = 124;

    public final static int FRAME_attak311 = 125;

    public final static int FRAME_attak312 = 126;

    public final static int FRAME_attak313 = 127;

    public final static int FRAME_attak314 = 128;

    public final static int FRAME_attak315 = 129;

    public final static int FRAME_attak316 = 130;

    public final static int FRAME_attak317 = 131;

    public final static int FRAME_attak318 = 132;

    public final static int FRAME_attak319 = 133;

    public final static int FRAME_attak320 = 134;

    public final static int FRAME_attak321 = 135;

    public final static int FRAME_attak322 = 136;

    public final static int FRAME_attak323 = 137;

    public final static int FRAME_attak324 = 138;

    public final static int FRAME_attak325 = 139;

    public final static int FRAME_attak326 = 140;

    public final static int FRAME_attak327 = 141;

    public final static int FRAME_attak328 = 142;

    public final static int FRAME_attak329 = 143;

    public final static int FRAME_attak330 = 144;

    public final static int FRAME_attak331 = 145;

    public final static int FRAME_attak332 = 146;

    public final static int FRAME_attak333 = 147;

    public final static int FRAME_attak334 = 148;

    public final static int FRAME_attak335 = 149;

    public final static int FRAME_attak336 = 150;

    public final static int FRAME_attak337 = 151;

    public final static int FRAME_attak338 = 152;

    public final static int FRAME_attak339 = 153;

    public final static int FRAME_attak340 = 154;

    public final static int FRAME_attak341 = 155;

    public final static int FRAME_attak342 = 156;

    public final static int FRAME_attak343 = 157;

    public final static int FRAME_attak344 = 158;

    public final static int FRAME_attak345 = 159;

    public final static int FRAME_attak346 = 160;

    public final static int FRAME_attak347 = 161;

    public final static int FRAME_attak348 = 162;

    public final static int FRAME_attak349 = 163;

    public final static int FRAME_attak350 = 164;

    public final static int FRAME_attak351 = 165;

    public final static int FRAME_attak352 = 166;

    public final static int FRAME_attak353 = 167;

    public final static int FRAME_attak401 = 168;

    public final static int FRAME_attak402 = 169;

    public final static int FRAME_attak403 = 170;

    public final static int FRAME_attak404 = 171;

    public final static int FRAME_attak405 = 172;

    public final static int FRAME_attak406 = 173;

    public final static int FRAME_attak407 = 174;

    public final static int FRAME_attak408 = 175;

    public final static int FRAME_attak409 = 176;

    public final static int FRAME_attak410 = 177;

    public final static int FRAME_attak411 = 178;

    public final static int FRAME_attak412 = 179;

    public final static int FRAME_attak413 = 180;

    public final static int FRAME_attak414 = 181;

    public final static int FRAME_attak415 = 182;

    public final static int FRAME_attak416 = 183;

    public final static int FRAME_attak417 = 184;

    public final static int FRAME_attak418 = 185;

    public final static int FRAME_attak419 = 186;

    public final static int FRAME_attak420 = 187;

    public final static int FRAME_attak421 = 188;

    public final static int FRAME_attak422 = 189;

    public final static int FRAME_attak423 = 190;

    public final static int FRAME_attak424 = 191;

    public final static int FRAME_attak425 = 192;

    public final static int FRAME_attak426 = 193;

    public final static int FRAME_attak427 = 194;

    public final static int FRAME_attak428 = 195;

    public final static int FRAME_attak429 = 196;

    public final static int FRAME_pain101 = 197;

    public final static int FRAME_pain102 = 198;

    public final static int FRAME_pain103 = 199;

    public final static int FRAME_pain104 = 200;

    public final static int FRAME_pain201 = 201;

    public final static int FRAME_pain202 = 202;

    public final static int FRAME_pain203 = 203;

    public final static int FRAME_pain204 = 204;

    public final static int FRAME_pain205 = 205;

    public final static int FRAME_pain301 = 206;

    public final static int FRAME_pain302 = 207;

    public final static int FRAME_pain303 = 208;

    public final static int FRAME_pain304 = 209;

    public final static int FRAME_pain305 = 210;

    public final static int FRAME_pain306 = 211;

    public final static int FRAME_pain307 = 212;

    public final static int FRAME_pain308 = 213;

    public final static int FRAME_pain309 = 214;

    public final static int FRAME_pain310 = 215;

    public final static int FRAME_pain311 = 216;

    public final static int FRAME_pain312 = 217;

    public final static int FRAME_pain313 = 218;

    public final static int FRAME_pain314 = 219;

    public final static int FRAME_pain315 = 220;

    public final static int FRAME_pain316 = 221;

    public final static int FRAME_death101 = 222;

    public final static int FRAME_death102 = 223;

    public final static int FRAME_death103 = 224;

    public final static int FRAME_death104 = 225;

    public final static int FRAME_death105 = 226;

    public final static int FRAME_death106 = 227;

    public final static int FRAME_death107 = 228;

    public final static int FRAME_death108 = 229;

    public final static int FRAME_death109 = 230;

    public final static int FRAME_death110 = 231;

    public final static int FRAME_death111 = 232;

    public final static int FRAME_death112 = 233;

    public final static int FRAME_death113 = 234;

    public final static int FRAME_death114 = 235;

    public final static int FRAME_death115 = 236;

    public final static int FRAME_death116 = 237;

    public final static int FRAME_death117 = 238;

    public final static int FRAME_death118 = 239;

    public final static int FRAME_death119 = 240;

    public final static int FRAME_death120 = 241;

    public final static int FRAME_death121 = 242;

    public final static int FRAME_death122 = 243;

    public final static int FRAME_death123 = 244;

    public final static int FRAME_death124 = 245;

    public final static int FRAME_death125 = 246;

    public final static int FRAME_death126 = 247;

    public final static int FRAME_death127 = 248;

    public final static int FRAME_death128 = 249;

    public final static int FRAME_death129 = 250;

    public final static int FRAME_death130 = 251;

    public final static int FRAME_death131 = 252;

    public final static int FRAME_death132 = 253;

    public final static int FRAME_recln101 = 254;

    public final static int FRAME_recln102 = 255;

    public final static int FRAME_recln103 = 256;

    public final static int FRAME_recln104 = 257;

    public final static int FRAME_recln105 = 258;

    public final static int FRAME_recln106 = 259;

    public final static int FRAME_recln107 = 260;

    public final static int FRAME_recln108 = 261;

    public final static int FRAME_recln109 = 262;

    public final static int FRAME_recln110 = 263;

    public final static int FRAME_recln111 = 264;

    public final static int FRAME_recln112 = 265;

    public final static int FRAME_recln113 = 266;

    public final static int FRAME_recln114 = 267;

    public final static int FRAME_recln115 = 268;

    public final static int FRAME_recln116 = 269;

    public final static int FRAME_recln117 = 270;

    public final static int FRAME_recln118 = 271;

    public final static int FRAME_recln119 = 272;

    public final static int FRAME_recln120 = 273;

    public final static int FRAME_recln121 = 274;

    public final static int FRAME_recln122 = 275;

    public final static int FRAME_recln123 = 276;

    public final static int FRAME_recln124 = 277;

    public final static int FRAME_recln125 = 278;

    public final static int FRAME_recln126 = 279;

    public final static int FRAME_recln127 = 280;

    public final static int FRAME_recln128 = 281;

    public final static int FRAME_recln129 = 282;

    public final static int FRAME_recln130 = 283;

    public final static int FRAME_recln131 = 284;

    public final static int FRAME_recln132 = 285;

    public final static int FRAME_recln133 = 286;

    public final static int FRAME_recln134 = 287;

    public final static int FRAME_recln135 = 288;

    public final static int FRAME_recln136 = 289;

    public final static int FRAME_recln137 = 290;

    public final static int FRAME_recln138 = 291;

    public final static int FRAME_recln139 = 292;

    public final static int FRAME_recln140 = 293;

    public final static float MODEL_SCALE = 1.000000f;

    static int sound_thud;

    static int sound_pain;

    static int sound_idle;

    static int sound_die;

    static int sound_step;

    static int sound_sight;

    static int sound_windup;

    static int sound_strike;

    //
    // misc
    //

    static EntInteractAdapter tank_sight = new EntInteractAdapter() {
    	public String getID(){ return "tank_sight"; }
        public boolean interact(Entity self, Entity other) {
            ServerGame.PF_StartSound(self, Constants.CHAN_VOICE, sound_sight, (float) 1, (float) Constants.ATTN_NORM,
            (float) 0);
            return true;
        }
    };

    static EntityThinkAdapter tank_footstep = new EntityThinkAdapter() {
    	public String getID(){ return "tank_footstep"; }
        public boolean think(Entity self) {
            ServerGame.PF_StartSound(self, Constants.CHAN_BODY, sound_step, (float) 1, (float) Constants.ATTN_NORM,
            (float) 0);
            return true;
        }
    };

    static EntityThinkAdapter tank_thud = new EntityThinkAdapter() {
    	public String getID(){ return "tank_thud"; }
        public boolean think(Entity self) {
            ServerGame.PF_StartSound(self, Constants.CHAN_BODY, sound_thud, (float) 1, (float) Constants.ATTN_NORM,
            (float) 0);
            return true;
        }
    };

    static EntityThinkAdapter tank_windup = new EntityThinkAdapter() {
    	public String getID(){ return "tank_windup"; }
        public boolean think(Entity self) {
            ServerGame.PF_StartSound(self, Constants.CHAN_WEAPON, sound_windup, (float) 1, (float) Constants.ATTN_NORM,
            (float) 0);
            return true;
        }
    };

    static EntityThinkAdapter tank_idle = new EntityThinkAdapter() {
    	public String getID(){ return "tank_idle"; }
        public boolean think(Entity self) {
            ServerGame.PF_StartSound(self, Constants.CHAN_VOICE, sound_idle, (float) 1, (float) Constants.ATTN_IDLE,
            (float) 0);
            return true;
        }
    };

    //
    // stand
    //

    static Frame tank_frames_stand[] = new Frame[] {
            new Frame(GameAI.ai_stand, 0, null),
            new Frame(GameAI.ai_stand, 0, null),
            new Frame(GameAI.ai_stand, 0, null),
            new Frame(GameAI.ai_stand, 0, null),
            new Frame(GameAI.ai_stand, 0, null),
            new Frame(GameAI.ai_stand, 0, null),
            new Frame(GameAI.ai_stand, 0, null),
            new Frame(GameAI.ai_stand, 0, null),
            new Frame(GameAI.ai_stand, 0, null),
            new Frame(GameAI.ai_stand, 0, null),
            new Frame(GameAI.ai_stand, 0, null),
            new Frame(GameAI.ai_stand, 0, null),
            new Frame(GameAI.ai_stand, 0, null),
            new Frame(GameAI.ai_stand, 0, null),
            new Frame(GameAI.ai_stand, 0, null),
            new Frame(GameAI.ai_stand, 0, null),
            new Frame(GameAI.ai_stand, 0, null),
            new Frame(GameAI.ai_stand, 0, null),
            new Frame(GameAI.ai_stand, 0, null),
            new Frame(GameAI.ai_stand, 0, null),
            new Frame(GameAI.ai_stand, 0, null),
            new Frame(GameAI.ai_stand, 0, null),
            new Frame(GameAI.ai_stand, 0, null),
            new Frame(GameAI.ai_stand, 0, null),
            new Frame(GameAI.ai_stand, 0, null),
            new Frame(GameAI.ai_stand, 0, null),
            new Frame(GameAI.ai_stand, 0, null),
            new Frame(GameAI.ai_stand, 0, null),
            new Frame(GameAI.ai_stand, 0, null),
            new Frame(GameAI.ai_stand, 0, null) };

    static MonsterMove tank_move_stand = new MonsterMove(FRAME_stand01, FRAME_stand30,
            tank_frames_stand, null);

    static EntityThinkAdapter tank_stand = new EntityThinkAdapter() {
    	public String getID(){ return "tank_stand"; }
        public boolean think(Entity self) {
            self.monsterinfo.currentmove = tank_move_stand;
            return true;
        }
    };

    //
    // walk
    //
    static EntityThinkAdapter tank_run = new EntityThinkAdapter() {
    	public String getID(){ return "tank_run"; }
        public boolean think(Entity self) {
            if (self.enemy != null && self.enemy.client != null)
                self.monsterinfo.aiflags |= Constants.AI_BRUTAL;
            else
                self.monsterinfo.aiflags &= ~Constants.AI_BRUTAL;

            if ((self.monsterinfo.aiflags & Constants.AI_STAND_GROUND) != 0) {
                self.monsterinfo.currentmove = tank_move_stand;
                return true;
            }

            if (self.monsterinfo.currentmove == tank_move_walk
                    || self.monsterinfo.currentmove == tank_move_start_run) {
                self.monsterinfo.currentmove = tank_move_run;
            } else {
                self.monsterinfo.currentmove = tank_move_start_run;
            }
            return true;
        }
    };

    static EntityThinkAdapter tank_walk = new EntityThinkAdapter() {
    	public String getID(){ return "tank_walk"; }
        public boolean think(Entity self) {
            self.monsterinfo.currentmove = tank_move_walk;
            return true;
        }
    };

    static Frame tank_frames_start_walk[] = new Frame[] {
            new Frame(GameAI.ai_walk, 0, null),
            new Frame(GameAI.ai_walk, 6, null),
            new Frame(GameAI.ai_walk, 6, null),
            new Frame(GameAI.ai_walk, 11, tank_footstep) };

    static MonsterMove tank_move_start_walk = new MonsterMove(FRAME_walk01,
            FRAME_walk04, tank_frames_start_walk, tank_walk);

    static Frame tank_frames_walk[] = new Frame[] {
            new Frame(GameAI.ai_walk, 4, null),
            new Frame(GameAI.ai_walk, 5, null),
            new Frame(GameAI.ai_walk, 3, null),
            new Frame(GameAI.ai_walk, 2, null),
            new Frame(GameAI.ai_walk, 5, null),
            new Frame(GameAI.ai_walk, 5, null),
            new Frame(GameAI.ai_walk, 4, null),
            new Frame(GameAI.ai_walk, 4, tank_footstep),
            new Frame(GameAI.ai_walk, 3, null),
            new Frame(GameAI.ai_walk, 5, null),
            new Frame(GameAI.ai_walk, 4, null),
            new Frame(GameAI.ai_walk, 5, null),
            new Frame(GameAI.ai_walk, 7, null),
            new Frame(GameAI.ai_walk, 7, null),
            new Frame(GameAI.ai_walk, 6, null),
            new Frame(GameAI.ai_walk, 6, tank_footstep) };

    static MonsterMove tank_move_walk = new MonsterMove(FRAME_walk05, FRAME_walk20,
            tank_frames_walk, null);

    static Frame tank_frames_stop_walk[] = new Frame[] {
            new Frame(GameAI.ai_walk, 3, null),
            new Frame(GameAI.ai_walk, 3, null),
            new Frame(GameAI.ai_walk, 2, null),
            new Frame(GameAI.ai_walk, 2, null),
            new Frame(GameAI.ai_walk, 4, tank_footstep) };

    static MonsterMove tank_move_stop_walk = new MonsterMove(FRAME_walk21,
            FRAME_walk25, tank_frames_stop_walk, tank_stand);

    //
    // run
    //

    static Frame tank_frames_start_run[] = new Frame[] {
            new Frame(GameAI.ai_run, 0, null),
            new Frame(GameAI.ai_run, 6, null),
            new Frame(GameAI.ai_run, 6, null),
            new Frame(GameAI.ai_run, 11, tank_footstep) };

    static MonsterMove tank_move_start_run = new MonsterMove(FRAME_walk01,
            FRAME_walk04, tank_frames_start_run, tank_run);

    static Frame tank_frames_run[] = new Frame[] {
            new Frame(GameAI.ai_run, 4, null),
            new Frame(GameAI.ai_run, 5, null),
            new Frame(GameAI.ai_run, 3, null),
            new Frame(GameAI.ai_run, 2, null),
            new Frame(GameAI.ai_run, 5, null),
            new Frame(GameAI.ai_run, 5, null),
            new Frame(GameAI.ai_run, 4, null),
            new Frame(GameAI.ai_run, 4, tank_footstep),
            new Frame(GameAI.ai_run, 3, null),
            new Frame(GameAI.ai_run, 5, null),
            new Frame(GameAI.ai_run, 4, null),
            new Frame(GameAI.ai_run, 5, null),
            new Frame(GameAI.ai_run, 7, null),
            new Frame(GameAI.ai_run, 7, null),
            new Frame(GameAI.ai_run, 6, null),
            new Frame(GameAI.ai_run, 6, tank_footstep) };

    static MonsterMove tank_move_run = new MonsterMove(FRAME_walk05, FRAME_walk20,
            tank_frames_run, null);

    static Frame tank_frames_stop_run[] = new Frame[] {
            new Frame(GameAI.ai_run, 3, null),
            new Frame(GameAI.ai_run, 3, null),
            new Frame(GameAI.ai_run, 2, null),
            new Frame(GameAI.ai_run, 2, null),
            new Frame(GameAI.ai_run, 4, tank_footstep) };

    static MonsterMove tank_move_stop_run = new MonsterMove(FRAME_walk21, FRAME_walk25,
            tank_frames_stop_run, tank_walk);

    //
    // pain
    //

    static Frame tank_frames_pain1[] = new Frame[] {
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null) };

    static MonsterMove tank_move_pain1 = new MonsterMove(FRAME_pain101, FRAME_pain104,
            tank_frames_pain1, tank_run);

    static Frame tank_frames_pain2[] = new Frame[] {
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null) };

    static MonsterMove tank_move_pain2 = new MonsterMove(FRAME_pain201, FRAME_pain205,
            tank_frames_pain2, tank_run);

    static Frame tank_frames_pain3[] = new Frame[] {
            new Frame(GameAI.ai_move, -7, null),
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 2, null),
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 3, null),
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 2, null),
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, tank_footstep) };

    static MonsterMove tank_move_pain3 = new MonsterMove(FRAME_pain301, FRAME_pain316,
            tank_frames_pain3, tank_run);

    static EntityPainAdapter tank_pain = new EntityPainAdapter() {
    	public String getID(){ return "tank_pain"; }
        public void pain(Entity self, Entity other, float kick, int damage) {
            if (self.health < (self.max_health / 2))
                self.s.skinnum |= 1;

            if (damage <= 10)
                return;

            if (GameBase.level.time < self.pain_debounce_time)
                return;

            if (damage <= 30)
                if (Lib.random() > 0.2)
                    return;

            // If hard or nightmare, don't go into pain while attacking
            if (GameBase.skill.value >= 2) {
                if ((self.s.frame >= FRAME_attak301)
                        && (self.s.frame <= FRAME_attak330))
                    return;
                if ((self.s.frame >= FRAME_attak101)
                        && (self.s.frame <= FRAME_attak116))
                    return;
            }

            self.pain_debounce_time = GameBase.level.time + 3;
            ServerGame.PF_StartSound(self, Constants.CHAN_VOICE, sound_pain, (float) 1, (float) Constants.ATTN_NORM,
            (float) 0);

            if (GameBase.skill.value == 3)
                return; // no pain anims in nightmare

            if (damage <= 30)
                self.monsterinfo.currentmove = tank_move_pain1;
            else if (damage <= 60)
                self.monsterinfo.currentmove = tank_move_pain2;
            else
                self.monsterinfo.currentmove = tank_move_pain3;
        }
    };

    //
    // attacks
    //

    static EntityThinkAdapter TankBlaster = new EntityThinkAdapter() {
    	public String getID(){ return "TankBlaster"; }
        public boolean think(Entity self) {
            float[] forward = { 0, 0, 0 }, right = { 0, 0, 0 };
            float[] start = { 0, 0, 0 };
            float[] end = { 0, 0, 0 };
            float[] dir = { 0, 0, 0 };
            int flash_number;

            if (self.s.frame == FRAME_attak110)
                flash_number = Constants.MZ2_TANK_BLASTER_1;
            else if (self.s.frame == FRAME_attak113)
                flash_number = Constants.MZ2_TANK_BLASTER_2;
            else
                // (self.s.frame == FRAME_attak116)
                flash_number = Constants.MZ2_TANK_BLASTER_3;

            Math3D.AngleVectors(self.s.angles, forward, right, null);
            Math3D.G_ProjectSource(self.s.origin,
                    MonsterFlash.monster_flash_offset[flash_number], forward, right,
                    start);

            Math3D.VectorCopy(self.enemy.s.origin, end);
            end[2] += self.enemy.viewheight;
            Math3D.VectorSubtract(end, start, dir);

            Monster.monster_fire_blaster(self, start, dir, 30, 800,
                    flash_number, Constants.EF_BLASTER);

            return true;
        }
    };

    static EntityThinkAdapter TankStrike = new EntityThinkAdapter() {
    	public String getID(){ return "TankStrike"; }
        public boolean think(Entity self) {
            ServerGame.PF_StartSound(self, Constants.CHAN_WEAPON, sound_strike, (float) 1, (float) Constants.ATTN_NORM,
            (float) 0);

            return true;
        }
    };

    static EntityThinkAdapter TankRocket = new EntityThinkAdapter() {
    	public String getID(){ return "TankRocket"; }
        public boolean think(Entity self) {
            float[] forward = { 0, 0, 0 }, right = { 0, 0, 0 };
            float[] start = { 0, 0, 0 };
            float[] dir = { 0, 0, 0 };
            float[] vec = { 0, 0, 0 };
            int flash_number;

            if (self.s.frame == FRAME_attak324)
                flash_number = Constants.MZ2_TANK_ROCKET_1;
            else if (self.s.frame == FRAME_attak327)
                flash_number = Constants.MZ2_TANK_ROCKET_2;
            else
                // (self.s.frame == FRAME_attak330)
                flash_number = Constants.MZ2_TANK_ROCKET_3;

            Math3D.AngleVectors(self.s.angles, forward, right, null);
            Math3D.G_ProjectSource(self.s.origin,
                    MonsterFlash.monster_flash_offset[flash_number], forward, right,
                    start);

            Math3D.VectorCopy(self.enemy.s.origin, vec);
            vec[2] += self.enemy.viewheight;
            Math3D.VectorSubtract(vec, start, dir);
            Math3D.VectorNormalize(dir);

            Monster
                    .monster_fire_rocket(self, start, dir, 50, 550,
                            flash_number);
            return true;
        }
    };

    static EntityThinkAdapter TankMachineGun = new EntityThinkAdapter() {
    	public String getID(){ return "TankMachineGun"; }
        public boolean think(Entity self) {

            float[] dir = { 0, 0, 0 };
            float[] vec = { 0, 0, 0 };
            float[] start = { 0, 0, 0 };
            float[] forward = { 0, 0, 0 }, right = { 0, 0, 0 };
            int flash_number;

            flash_number = Constants.MZ2_TANK_MACHINEGUN_1
                    + (self.s.frame - FRAME_attak406);

            Math3D.AngleVectors(self.s.angles, forward, right, null);
            Math3D.G_ProjectSource(self.s.origin,
                    MonsterFlash.monster_flash_offset[flash_number], forward, right,
                    start);

            if (self.enemy != null) {
                Math3D.VectorCopy(self.enemy.s.origin, vec);
                vec[2] += self.enemy.viewheight;
                Math3D.VectorSubtract(vec, start, vec);
                Math3D.vectoangles(vec, vec);
                dir[0] = vec[0];
            } else {
                dir[0] = 0;
            }
            if (self.s.frame <= FRAME_attak415)
                dir[1] = self.s.angles[1] - 8 * (self.s.frame - FRAME_attak411);
            else
                dir[1] = self.s.angles[1] + 8 * (self.s.frame - FRAME_attak419);
            dir[2] = 0;

            Math3D.AngleVectors(dir, forward, null, null);

            Monster.monster_fire_bullet(self, start, forward, 20, 4,
                    Constants.DEFAULT_BULLET_HSPREAD,
                    Constants.DEFAULT_BULLET_VSPREAD, flash_number);

            return true;
        }
    };

    static EntityThinkAdapter tank_reattack_blaster = new EntityThinkAdapter() {
    	public String getID(){ return "tank_reattack_blaster"; }
        public boolean think(Entity self) {
            if (GameBase.skill.value >= 2)
                if (GameUtil.visible(self, self.enemy))
                    if (self.enemy.health > 0)
                        if (Lib.random() <= 0.6) {
                            self.monsterinfo.currentmove = tank_move_reattack_blast;
                            return true;
                        }
            self.monsterinfo.currentmove = tank_move_attack_post_blast;
            return true;
        }
    };

    static Frame tank_frames_attack_blast[] = new Frame[] {
            new Frame(GameAI.ai_charge, 0, null),
            new Frame(GameAI.ai_charge, 0, null),
            new Frame(GameAI.ai_charge, 0, null),
            new Frame(GameAI.ai_charge, 0, null),
            new Frame(GameAI.ai_charge, -1, null),
            new Frame(GameAI.ai_charge, -2, null),
            new Frame(GameAI.ai_charge, -1, null),
            new Frame(GameAI.ai_charge, -1, null),
            new Frame(GameAI.ai_charge, 0, null),
            new Frame(GameAI.ai_charge, 0, TankBlaster),
            // 10
            new Frame(GameAI.ai_charge, 0, null),
            new Frame(GameAI.ai_charge, 0, null),
            new Frame(GameAI.ai_charge, 0, TankBlaster),
            new Frame(GameAI.ai_charge, 0, null),
            new Frame(GameAI.ai_charge, 0, null),
            new Frame(GameAI.ai_charge, 0, TankBlaster) // 16
    };

    static MonsterMove tank_move_attack_blast = new MonsterMove(FRAME_attak101,
            FRAME_attak116, tank_frames_attack_blast, tank_reattack_blaster);

    static Frame tank_frames_reattack_blast[] = new Frame[] {
            new Frame(GameAI.ai_charge, 0, null),
            new Frame(GameAI.ai_charge, 0, null),
            new Frame(GameAI.ai_charge, 0, TankBlaster),
            new Frame(GameAI.ai_charge, 0, null),
            new Frame(GameAI.ai_charge, 0, null),
            new Frame(GameAI.ai_charge, 0, TankBlaster) // 16)
    };

    static MonsterMove tank_move_reattack_blast = new MonsterMove(FRAME_attak111,
            FRAME_attak116, tank_frames_reattack_blast, tank_reattack_blaster);

    static Frame tank_frames_attack_post_blast[] = new Frame[] {
            new Frame(GameAI.ai_move, 0, null), // 17)
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 2, null),
            new Frame(GameAI.ai_move, 3, null),
            new Frame(GameAI.ai_move, 2, null),
            new Frame(GameAI.ai_move, -2, tank_footstep) // 22
    };

    static MonsterMove tank_move_attack_post_blast = new MonsterMove(FRAME_attak117,
            FRAME_attak122, tank_frames_attack_post_blast, tank_run);

    static EntityThinkAdapter tank_poststrike = new EntityThinkAdapter() {
    	public String getID(){ return "tank_poststrike"; }
        public boolean think(Entity self) {
            self.enemy = null;
            tank_run.think(self);
            return true;
        }
    };

    static EntityThinkAdapter tank_doattack_rocket = new EntityThinkAdapter() {
    	public String getID(){ return "tank_doattack_rocket"; }
        public boolean think(Entity self) {
            self.monsterinfo.currentmove = tank_move_attack_fire_rocket;
            return true;
        }
    };

    static EntityThinkAdapter tank_refire_rocket = new EntityThinkAdapter() {
    	public String getID(){ return "tank_refire_rocket"; }
        public boolean think(Entity self) {
            // Only on hard or nightmare
            if (GameBase.skill.value >= 2)
                if (self.enemy.health > 0)
                    if (GameUtil.visible(self, self.enemy))
                        if (Lib.random() <= 0.4) {
                            self.monsterinfo.currentmove = tank_move_attack_fire_rocket;
                            return true;
                        }
            self.monsterinfo.currentmove = tank_move_attack_post_rocket;
            return true;
        }
    };

    static Frame tank_frames_attack_strike[] = new Frame[] {
            new Frame(GameAI.ai_move, 3, null),
            new Frame(GameAI.ai_move, 2, null),
            new Frame(GameAI.ai_move, 2, null),
            new Frame(GameAI.ai_move, 1, null),
            new Frame(GameAI.ai_move, 6, null),
            new Frame(GameAI.ai_move, 7, null),
            new Frame(GameAI.ai_move, 9, tank_footstep),
            new Frame(GameAI.ai_move, 2, null),
            new Frame(GameAI.ai_move, 1, null),
            new Frame(GameAI.ai_move, 2, null),
            new Frame(GameAI.ai_move, 2, tank_footstep),
            new Frame(GameAI.ai_move, 2, null),
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, -2, null),
            new Frame(GameAI.ai_move, -2, null),
            new Frame(GameAI.ai_move, 0, tank_windup),
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, TankStrike),
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, -1, null),
            new Frame(GameAI.ai_move, -1, null),
            new Frame(GameAI.ai_move, -1, null),
            new Frame(GameAI.ai_move, -1, null),
            new Frame(GameAI.ai_move, -1, null),
            new Frame(GameAI.ai_move, -3, null),
            new Frame(GameAI.ai_move, -10, null),
            new Frame(GameAI.ai_move, -10, null),
            new Frame(GameAI.ai_move, -2, null),
            new Frame(GameAI.ai_move, -3, null),
            new Frame(GameAI.ai_move, -2, tank_footstep) };

    static MonsterMove tank_move_attack_strike = new MonsterMove(FRAME_attak201,
            FRAME_attak238, tank_frames_attack_strike, tank_poststrike);

    static Frame tank_frames_attack_pre_rocket[] = new Frame[] {
            new Frame(GameAI.ai_charge, 0, null),
            new Frame(GameAI.ai_charge, 0, null),
            new Frame(GameAI.ai_charge, 0, null),
            new Frame(GameAI.ai_charge, 0, null),
            new Frame(GameAI.ai_charge, 0, null),
            new Frame(GameAI.ai_charge, 0, null),
            new Frame(GameAI.ai_charge, 0, null),
            new Frame(GameAI.ai_charge, 0, null),
            new Frame(GameAI.ai_charge, 0, null),
            new Frame(GameAI.ai_charge, 0, null),
            // 10)

            new Frame(GameAI.ai_charge, 0, null),
            new Frame(GameAI.ai_charge, 1, null),
            new Frame(GameAI.ai_charge, 2, null),
            new Frame(GameAI.ai_charge, 7, null),
            new Frame(GameAI.ai_charge, 7, null),
            new Frame(GameAI.ai_charge, 7, tank_footstep),
            new Frame(GameAI.ai_charge, 0, null),
            new Frame(GameAI.ai_charge, 0, null),
            new Frame(GameAI.ai_charge, 0, null),
            new Frame(GameAI.ai_charge, 0, null),
            // 20)

            new Frame(GameAI.ai_charge, -3, null) };

    static MonsterMove tank_move_attack_pre_rocket = new MonsterMove(FRAME_attak301,
            FRAME_attak321, tank_frames_attack_pre_rocket, tank_doattack_rocket);

    static Frame tank_frames_attack_fire_rocket[] = new Frame[] {
            new Frame(GameAI.ai_charge, -3, null), // Loop Start 22 )
            new Frame(GameAI.ai_charge, 0, null),
            new Frame(GameAI.ai_charge, 0, TankRocket), // 24)
            new Frame(GameAI.ai_charge, 0, null),
            new Frame(GameAI.ai_charge, 0, null),
            new Frame(GameAI.ai_charge, 0, TankRocket),
            new Frame(GameAI.ai_charge, 0, null),
            new Frame(GameAI.ai_charge, 0, null),
            new Frame(GameAI.ai_charge, -1, TankRocket) // 30 Loop End
    };

    static MonsterMove tank_move_attack_fire_rocket = new MonsterMove(FRAME_attak322,
            FRAME_attak330, tank_frames_attack_fire_rocket, tank_refire_rocket);

    static Frame tank_frames_attack_post_rocket[] = new Frame[] {
            new Frame(GameAI.ai_charge, 0, null), // 31)
            new Frame(GameAI.ai_charge, -1, null),
            new Frame(GameAI.ai_charge, -1, null),
            new Frame(GameAI.ai_charge, 0, null),
            new Frame(GameAI.ai_charge, 2, null),
            new Frame(GameAI.ai_charge, 3, null),
            new Frame(GameAI.ai_charge, 4, null),
            new Frame(GameAI.ai_charge, 2, null),
            new Frame(GameAI.ai_charge, 0, null),
            new Frame(GameAI.ai_charge, 0, null),
            // 40)

            new Frame(GameAI.ai_charge, 0, null),
            new Frame(GameAI.ai_charge, -9, null),
            new Frame(GameAI.ai_charge, -8, null),
            new Frame(GameAI.ai_charge, -7, null),
            new Frame(GameAI.ai_charge, -1, null),
            new Frame(GameAI.ai_charge, -1, tank_footstep),
            new Frame(GameAI.ai_charge, 0, null),
            new Frame(GameAI.ai_charge, 0, null),
            new Frame(GameAI.ai_charge, 0, null),
            new Frame(GameAI.ai_charge, 0, null),
            // 50)

            new Frame(GameAI.ai_charge, 0, null),
            new Frame(GameAI.ai_charge, 0, null),
            new Frame(GameAI.ai_charge, 0, null) };

    static MonsterMove tank_move_attack_post_rocket = new MonsterMove(FRAME_attak331,
            FRAME_attak353, tank_frames_attack_post_rocket, tank_run);

    static Frame tank_frames_attack_chain[] = new Frame[] {
            new Frame(GameAI.ai_charge, 0, null),
            new Frame(GameAI.ai_charge, 0, null),
            new Frame(GameAI.ai_charge, 0, null),
            new Frame(GameAI.ai_charge, 0, null),
            new Frame(GameAI.ai_charge, 0, null),
            new Frame(null, 0, TankMachineGun),
            new Frame(null, 0, TankMachineGun),
            new Frame(null, 0, TankMachineGun),
            new Frame(null, 0, TankMachineGun),
            new Frame(null, 0, TankMachineGun),
            new Frame(null, 0, TankMachineGun),
            new Frame(null, 0, TankMachineGun),
            new Frame(null, 0, TankMachineGun),
            new Frame(null, 0, TankMachineGun),
            new Frame(null, 0, TankMachineGun),
            new Frame(null, 0, TankMachineGun),
            new Frame(null, 0, TankMachineGun),
            new Frame(null, 0, TankMachineGun),
            new Frame(null, 0, TankMachineGun),
            new Frame(null, 0, TankMachineGun),
            new Frame(null, 0, TankMachineGun),
            new Frame(null, 0, TankMachineGun),
            new Frame(null, 0, TankMachineGun),
            new Frame(null, 0, TankMachineGun),
            new Frame(GameAI.ai_charge, 0, null),
            new Frame(GameAI.ai_charge, 0, null),
            new Frame(GameAI.ai_charge, 0, null),
            new Frame(GameAI.ai_charge, 0, null),
            new Frame(GameAI.ai_charge, 0, null) };

    static MonsterMove tank_move_attack_chain = new MonsterMove(FRAME_attak401,
            FRAME_attak429, tank_frames_attack_chain, tank_run);

    static EntityThinkAdapter tank_attack = new EntityThinkAdapter() {
    	public String getID(){ return "tank_attack"; }
        public boolean think(Entity self) {
            float[] vec = { 0, 0, 0 };
            float range;
            float r;

            if (self.enemy.health < 0) {
                self.monsterinfo.currentmove = tank_move_attack_strike;
                self.monsterinfo.aiflags &= ~Constants.AI_BRUTAL;
                return true;
            }

            Math3D.VectorSubtract(self.enemy.s.origin, self.s.origin, vec);
            range = Math3D.VectorLength(vec);

            r = Lib.random();

            if (range <= 125) {
                if (r < 0.4)
                    self.monsterinfo.currentmove = tank_move_attack_chain;
                else
                    self.monsterinfo.currentmove = tank_move_attack_blast;
            } else if (range <= 250) {
                if (r < 0.5)
                    self.monsterinfo.currentmove = tank_move_attack_chain;
                else
                    self.monsterinfo.currentmove = tank_move_attack_blast;
            } else {
                if (r < 0.33)
                    self.monsterinfo.currentmove = tank_move_attack_chain;
                else if (r < 0.66) {
                    self.monsterinfo.currentmove = tank_move_attack_pre_rocket;
                    self.pain_debounce_time = GameBase.level.time + 5.0f; // no
                                                                          // pain
                                                                          // for
                                                                          // a
                                                                          // while
                } else
                    self.monsterinfo.currentmove = tank_move_attack_blast;
            }
            return true;
        }
    };

    //
    // death
    //
    static EntityThinkAdapter tank_dead = new EntityThinkAdapter() {
    	public String getID(){ return "tank_dead"; }
        public boolean think(Entity self) {
            Math3D.VectorSet(self.mins, -16, -16, -16);
            Math3D.VectorSet(self.maxs, 16, 16, -0);
            self.movetype = Constants.MOVETYPE_TOSS;
            self.svflags |= Constants.SVF_DEADMONSTER;
            self.nextthink = 0;
            World.SV_LinkEdict(self);
            return true;
        }
    };

    static Frame tank_frames_death1[] = new Frame[] {
            new Frame(GameAI.ai_move, -7, null),
            new Frame(GameAI.ai_move, -2, null),
            new Frame(GameAI.ai_move, -2, null),
            new Frame(GameAI.ai_move, 1, null),
            new Frame(GameAI.ai_move, 3, null),
            new Frame(GameAI.ai_move, 6, null),
            new Frame(GameAI.ai_move, 1, null),
            new Frame(GameAI.ai_move, 1, null),
            new Frame(GameAI.ai_move, 2, null),
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, -2, null),
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, -3, null),
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, -4, null),
            new Frame(GameAI.ai_move, -6, null),
            new Frame(GameAI.ai_move, -4, null),
            new Frame(GameAI.ai_move, -5, null),
            new Frame(GameAI.ai_move, -7, null),
            new Frame(GameAI.ai_move, -15, tank_thud),
            new Frame(GameAI.ai_move, -5, null),
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null),
            new Frame(GameAI.ai_move, 0, null) };

    static MonsterMove tank_move_death = new MonsterMove(FRAME_death101,
            FRAME_death132, tank_frames_death1, tank_dead);

    static EntityDieAdapter tank_die = new EntityDieAdapter() {
    	public String getID(){ return "tank_die"; }
        public void die(Entity self, Entity inflictor, Entity attacker,
                int damage, float[] point) {
            int n;

            // check for gib
            if (self.health <= self.gib_health) {
                ServerGame.PF_StartSound(self, Constants.CHAN_VOICE, ServerInit.SV_SoundIndex("misc/udeath.wav"), (float) 1, (float) Constants.ATTN_NORM,
                (float) 0);
                for (n = 0; n < 1 /* 4 */; n++)
                    GameMisc.ThrowGib(self,
                            "models/objects/gibs/sm_meat/tris.md2", damage,
                            Constants.GIB_ORGANIC);
                for (n = 0; n < 4; n++)
                    GameMisc.ThrowGib(self,
                            "models/objects/gibs/sm_metal/tris.md2", damage,
                            Constants.GIB_METALLIC);
                GameMisc.ThrowGib(self, "models/objects/gibs/chest/tris.md2",
                        damage, Constants.GIB_ORGANIC);
                GameMisc.ThrowHead(self, "models/objects/gibs/gear/tris.md2",
                        damage, Constants.GIB_METALLIC);
                self.deadflag = Constants.DEAD_DEAD;
                return;
            }

            if (self.deadflag == Constants.DEAD_DEAD)
                return;

            // regular death
            ServerGame.PF_StartSound(self, Constants.CHAN_VOICE, sound_die, (float) 1, (float) Constants.ATTN_NORM,
            (float) 0);
            self.deadflag = Constants.DEAD_DEAD;
            self.takedamage = Constants.DAMAGE_YES;

            self.monsterinfo.currentmove = tank_move_death;

        }
    };

    //
    // monster_tank
    //

    /*
     * QUAKED monster_tank (1 .5 0) (-32 -32 -16) (32 32 72) Ambush
     * Trigger_Spawn Sight
     */
    /*
     * QUAKED monster_tank_commander (1 .5 0) (-32 -32 -16) (32 32 72) Ambush
     * Trigger_Spawn Sight
     */
    public static EntityThinkAdapter SP_monster_tank = new EntityThinkAdapter() {
    	public String getID(){ return "SP_monster_tank"; }
        public boolean think(Entity self) {
            if (GameBase.deathmatch.value != 0) {
                GameUtil.G_FreeEdict(self);
                return true;
            }

            self.s.modelindex = ServerInit.SV_ModelIndex("models/monsters/tank/tris.md2");
            Math3D.VectorSet(self.mins, -32, -32, -16);
            Math3D.VectorSet(self.maxs, 32, 32, 72);
            self.movetype = Constants.MOVETYPE_STEP;
            self.solid = Constants.SOLID_BBOX;

            sound_pain = ServerInit.SV_SoundIndex("tank/tnkpain2.wav");
            sound_thud = ServerInit.SV_SoundIndex("tank/tnkdeth2.wav");
            sound_idle = ServerInit.SV_SoundIndex("tank/tnkidle1.wav");
            sound_die = ServerInit.SV_SoundIndex("tank/death.wav");
            sound_step = ServerInit.SV_SoundIndex("tank/step.wav");
            sound_windup = ServerInit.SV_SoundIndex("tank/tnkatck4.wav");
            sound_strike = ServerInit.SV_SoundIndex("tank/tnkatck5.wav");
            sound_sight = ServerInit.SV_SoundIndex("tank/sight1.wav");

            ServerInit.SV_SoundIndex("tank/tnkatck1.wav");
            ServerInit.SV_SoundIndex("tank/tnkatk2a.wav");
            ServerInit.SV_SoundIndex("tank/tnkatk2b.wav");
            ServerInit.SV_SoundIndex("tank/tnkatk2c.wav");
            ServerInit.SV_SoundIndex("tank/tnkatk2d.wav");
            ServerInit.SV_SoundIndex("tank/tnkatk2e.wav");
            ServerInit.SV_SoundIndex("tank/tnkatck3.wav");

            if (Lib.strcmp(self.classname, "monster_tank_commander") == 0) {
                self.health = 1000;
                self.gib_health = -225;
            } else {
                self.health = 750;
                self.gib_health = -200;
            }

            self.mass = 500;

            self.pain = tank_pain;
            self.die = tank_die;
            self.monsterinfo.stand = tank_stand;
            self.monsterinfo.walk = tank_walk;
            self.monsterinfo.run = tank_run;
            self.monsterinfo.dodge = null;
            self.monsterinfo.attack = tank_attack;
            self.monsterinfo.melee = null;
            self.monsterinfo.sight = tank_sight;
            self.monsterinfo.idle = tank_idle;

            World.SV_LinkEdict(self);

            self.monsterinfo.currentmove = tank_move_stand;
            self.monsterinfo.scale = MODEL_SCALE;

            GameAI.walkmonster_start.think(self);

            if (Lib.strcmp(self.classname, "monster_tank_commander") == 0)
                self.s.skinnum = 2;
            return true;
        }
    };

}
